package com.luobo.shiro.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.luobo.shiro.bean.CacheUser;
import com.luobo.shiro.bean.LocalUser;
import com.luobo.shiro.domain.entity.User;
import com.luobo.shiro.domain.mapper.UserMapper;
import com.luobo.shiro.service.IUserService;
import com.luobo.shiro.web.exception.LoginException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class UserServiceImpl implements IUserService {

    @Autowired
  private UserMapper userMapper;


    @Override
    public User findByUsername(String username) {
        return userMapper.selectOne(new QueryWrapper<User>().eq("userName",username));
    }

    @Override
    public CacheUser login(String userName, String password) {

        // 获取Subject实例对象，用户实例
        Subject subject = SecurityUtils.getSubject();
        LocalUser.init(userName);
        // 将用户名和密码封装到UsernamePasswordToken
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
        CacheUser cacheUser;

        // 4、认证
        try {
            // 传到 MyShiroRealm 类中的方法进行认证
            subject.login(token);
            // 构建缓存用户信息返回给前端
            User user = (User) subject.getPrincipals().getPrimaryPrincipal();
            cacheUser = CacheUser.builder()
                    .token(subject.getSession().getId().toString())
                    .build();
            BeanUtils.copyProperties(user, cacheUser);
            log.warn("CacheUser is {}", cacheUser.toString());
        } catch (UnknownAccountException e) {
            log.error("账户不存在异常：", e);
            throw new LoginException("账号不存在!", e);
        } catch (IncorrectCredentialsException e) {
            log.error("凭据错误（密码错误）异常：", e);
            throw new LoginException("密码不正确!", e);
        } catch (AuthenticationException e) {
            log.error("身份验证异常:", e);
            throw new LoginException("用户验证失败!", e);
        }
        return cacheUser;
    }

    @Override
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
    }

    @Override
    public List<User> listUsers() {
        return userMapper.selectList(null);
    }

    @Override
    public Integer insert(User user) {

        String salt = UUID.randomUUID().toString().replace("-","");
        String password = user.getPassword();
        user.setSalt(salt);
        String credentialsSalt = user.getCredentialsSalt();
        String pwd = new Md5Hash(password,credentialsSalt, 3).toString();
        user.setCreateTime(new Date());
        user.setExpiredDate(new Date());
        user.setPassword(pwd);
        return userMapper.insert(user);
    }
}
